package com.example.fitts_app

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import kotlin.math.cos
import kotlin.math.min
import kotlin.math.sin
import kotlin.random.Random
import android.util.Log
class FittsView(context: Context, attrs: AttributeSet?) : View(context, attrs) {

    private val paintGreen = Paint().apply { color = Color.GREEN }
    private val paintGray = Paint().apply { color = Color.GRAY }
    private val paintRed = Paint().apply { color = Color.RED }

    var D = 61f // 控件间距
    var W = 1f // 红色方块宽度

    private var greenRect = RectF()
    private var redRect = RectF()

    private var greenClicked = false
    private var startTime = 0L
    private var currentAngle = 0.0

    var inputD: Float? = null
    var inputW: Float? = null


    private var listener: ((Float, Float, Float, Float, Float) -> Unit)? = null // (D, W, ID, T, angle)

    /** 刷新并生成新的红绿方块 */
    fun refreshTargets() {
        val minW = 30f
        val maxW = 200f

        val redWidthSize = if (W == 25f) {
            Random.nextFloat() * (maxW - minW) + minW  // → 随机范围 [10f, 200f)
        } else {
            W.coerceIn(minW, maxW) // 限制用户输入在 [30, 200] 内
        }

        val redHeightSize = redWidthSize  // 或者保持相同逻辑

        val greenSize = 120f
        val diagonalGreen = (greenSize * Math.sqrt(2.0)).toFloat()
        val diagonalRed = Math.sqrt(
            (redWidthSize / 2).toDouble() * (redWidthSize / 2).toDouble() +
                    (redHeightSize / 2).toDouble() * (redHeightSize / 2).toDouble()
        ).toFloat()

        val minDistance = diagonalGreen / 2 + diagonalRed / 2

        val viewWidth = width.toFloat().coerceAtLeast(200f)
        val viewHeight = height.toFloat().coerceAtLeast(400f)
        val maxDistance = min(viewWidth, viewHeight) / 2 - redWidthSize / 2

        val distance = if (D == 61f) {
            Random.nextFloat() * (maxDistance - minDistance) + minDistance
        } else {
            D.coerceIn(minDistance, maxDistance)
        }

        val centerX = viewWidth / 2
        val centerY = viewHeight / 2

        greenRect.set(
            centerX - greenSize / 2,
            centerY - greenSize / 2,
            centerX + greenSize / 2,
            centerY + greenSize / 2
        )

        var valid = false
        var rx = 0f
        var ry = 0f
        var angle = 0.0

        while (!valid) {
            angle = Random.nextDouble(0.0, 2 * Math.PI)
            currentAngle = angle
            val dx = (distance * cos(angle)).toFloat()
            val dy = (distance * sin(angle)).toFloat()
            rx = centerX + dx
            ry = centerY + dy

            val left = rx - redWidthSize / 2
            val top = ry - redHeightSize / 2
            val right = rx + redWidthSize / 2
            val bottom = ry + redHeightSize / 2
            valid = left >= 0 && right <= viewWidth && top >= 0 && bottom <= viewHeight
        }

        redRect.set(
            rx - redWidthSize / 2, ry - redHeightSize / 2,
            rx + redWidthSize / 2, ry + redHeightSize / 2
        )
        D = distance
        W =(redWidthSize+redHeightSize)/2
        greenClicked = false
        invalidate()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val paint = if (greenClicked) paintGray else paintGreen
        canvas.drawRect(greenRect, paint)
        canvas.drawRect(redRect, paintRed)
    }

    /** 处理用户点击 */
    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (event.action == MotionEvent.ACTION_DOWN) {
            val x = event.x
            val y = event.y

            if (greenRect.contains(x, y)&&!greenClicked ) {
                startTime = System.currentTimeMillis()
                greenClicked = true
                invalidate()
                return true
            }

            if (redRect.contains(x, y) && greenClicked) {
                val endTime = System.currentTimeMillis()
                val totalTime = endTime - startTime
                
                // 使用用户输入的原始D值保存，如果没有输入则使用计算出的实际D值
                val savedD = inputD?.takeIf { it > 0f } ?: D
                // 使用用户输入的原始W值保存，如果没有输入则使用计算出的实际W值
                val savedW = inputW?.takeIf { it > 0f } ?: W
                
                val id = (Math.log((savedD / savedW + 1).toDouble()) / Math.log(2.0)).toFloat()

                if (savedD > 0f && savedW > 0f) {
                    if (id.isFinite()) {
                        saveDataInMemory(savedD, savedW, totalTime.toFloat(), id)
                    }
                }
                // ✅ 判断用户是否输入了 D/W
                val newD = inputD?.takeIf { it > 0f } ?: 61f  // 默认61表示随机
                val newW = inputW?.takeIf { it > 0f } ?: 25f   // 默认25表示随机

                D=newD
                W=newW


                post { refreshTargets() }
                return true
            }
        }
        return true
    }

    private fun saveDataInMemory(D: Float, W: Float, T: Float, ID: Float) {
        try {
            // 过滤非法值，防止崩溃
            if (D <= 0f || W <= 0f || T <= 0f || !ID.isFinite() || !D.isFinite() || !W.isFinite() || !T.isFinite()) {
                Log.w("FittsView", "跳过无效数据: D=$D, W=$W, T=$T, ID=$ID")
                return
            }
            
            val record = FittsRecord(D, W, ID, T)
            FittsDataHolder.records.add(record)
            Log.d("FittsView", "已保存记录: $record")
        } catch (e: Exception) {
            Log.e("FittsView", "保存数据时出错", e)
        }
    }
    fun resetView() {
        // 清空方块区域
        greenRect.setEmpty()
        redRect.setEmpty()

        // 重置状态
        greenClicked = false
        startTime = 0L
        currentAngle = 0.0

        // 刷新画布
        invalidate()
    }
}
